package com.inibb.app.sftp;

import java.io.*;

public class RemoteFileEntry {
	
	private static final String DIR_STRING = "[DIR] ";
	private static final String FILE_STRING = "[FILE]";
	private static final String LINK_STRING = "[LINK]";
	private static final String FIELD_SEP = ":";
	private static final char TARGET_SEPERATOR = '/';
	
	public static final int TYPE_FILE = 0x00000000;
	public static final int TYPE_DIR  = 0x00004000;
	private static final int TYPE_NOT_DIR = 0xffffffff ^ TYPE_DIR;
	public static final int TYPE_LINK = 0x0000a000;
	private static final int TYPE_NOT_LINK = 0xffffffff ^ TYPE_LINK;
	
	private long fileSize = -1;
	private File remoteFile;
	private long lastModified = System.currentTimeMillis();
	//private boolean dir = false;
	private int type = TYPE_FILE;
	private String remoteFileString=null;
	private String remoteFilenameString=null;
	private String toStringStr=null;

	/**
	 * Construct a RemoteFileEntry using the given <code>path</code>
	 * @param path the path of targetted remote file/directory
	 */
	public RemoteFileEntry(File path) {
		remoteFile = path;
	}
	
	/**
	 * Construct a RemoteFileEntry using the given <code>path</code>
	 * @param path the path of targetted remote file/directory
	 */
	public RemoteFileEntry(String path) {
		remoteFile = new File(path);
	}
	
	/**
	 * Construct a RemoteFileEntry using the given <code>parent</code> and <code>child</code>
	 * @param parent the parent <code>RemoteFileEntry</code> 
	 * @param child the relative path to <code>parent</code>
	 */
	public RemoteFileEntry(RemoteFileEntry parent, String child) {
		remoteFile = new File(parent.remoteFile,child);
	}
	
	/**
	 * Get the parent directory of this <code>RemoteFileEntry</code>
	 * @return <code>RemoteFileEntry</code>
	 */
	public RemoteFileEntry getParent() {
		String _p = remoteFile.getParent();
		if (_p==null) return null;
		else return new RemoteFileEntry(_p);
	}
	
	/**
	 * Check if the remote file is a directory.
	 * @return true if this <code>RemoteFileEntry</code> is pointing to a remote directory.
	 */
	public boolean isDir() {
		return (type & TYPE_DIR) == TYPE_DIR;
	}
	
	public void setDir(boolean dir) {
		if (dir) type = type | TYPE_DIR;
		else type = type & TYPE_NOT_DIR;
	}

	/**
	 * Check if the remote file is a link.
	 * @return true if this <code>RemoteFileEntry</code> is pointing to a link.
	 */
	public boolean isLink() {
		return (type & TYPE_LINK) == TYPE_LINK;
	}
	
	public void setLink(boolean link) {
		if (link) type = type | TYPE_LINK;
		else type = type & TYPE_NOT_LINK;
	}
	
	/**
	 * Get the remote file size in byte.
	 * @return
	 */
	public long getFileSize() {
		return fileSize;
	}
	
	public void setFileSize(long fileSize) {
		this.fileSize = fileSize;
	}
	
	/**
	 * Get the file's last modified time in UTC long.
	 * @return
	 */
	public long getLastModified() {
		return lastModified;
	}
	
	public void setLastModified(long lastModified) {
		this.lastModified = lastModified;
	}
	
	/**
	 * Get the remote path of this <code>RemoteFileEntry</code> pointed to.
	 * @return <code>long</code>
	 */
	public String getRemoteFile() {
		if (remoteFileString==null) {
			remoteFileString = remoteFile.getPath().replace(File.separatorChar,TARGET_SEPERATOR);
		}
		return remoteFileString;
	}
	
	public String getRemoteFilename() {
		if (remoteFilenameString==null) {
			remoteFilenameString = remoteFile.getName();
		}
		return remoteFilenameString;
	}
	
	public void setRemoteFile(String remoteFile) {
		this.remoteFile = new File(remoteFile);
		clearResolveCache();
	}
	
	public void setRemoteFile(File remoteFile) {
		this.remoteFile = remoteFile;
		clearResolveCache();
	}

	public String toString() {
		if (toStringStr==null) {
			StringBuffer sb = new StringBuffer();
			if (isDir()) sb.append(DIR_STRING);
			else if (isLink()) sb.append(LINK_STRING);
			else sb.append(FILE_STRING);
			
			sb.append(FIELD_SEP);
			sb.append(getRemoteFile());
			
			toStringStr= sb.toString(); 
		}
		return toStringStr;
	}
	
	private void clearResolveCache() {
		remoteFileString=null;
		remoteFilenameString=null;
		toStringStr=null;
		
	}
		
}
